package com.xinchuang.service.targetSystem;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xinchuang.entity.targetSystem.system.PostureComputeType;
import com.xinchuang.entity.targetSystem.system.SystemsDynamic;
import com.xinchuang.entity.targetSystem.system.SystemsRelationship;
import com.xinchuang.entity.targetSystem.target.TargetData;
import com.xinchuang.mapper.targetSystem.TargetMapper;
import com.xinchuang.service.RedisUseService;
import com.xinchuang.service.targetSystem.target.PostureComputeTypeService;
import com.xinchuang.util.FileElseUtil;
import com.xinchuang.util.RedisUtil;
import com.xinchuang.utils.ObjectUtil;
import com.xinchuang.utils.RedisName;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;

@Service(value = "OverallAnalyseService")
@RequiredArgsConstructor
public class OverallAnalyseService {

    private final RedisUtil redisUtil;

    private final RedisUseService redisUseService;

    private final SystemsDynamicService systemsDynamicService;

    private final PostureComputeTypeService postureComputeTypeService;

    private final TargetMapper targetMapper;

    /**
     * 静态分析
     * @param sysId
     * @param targetStatic
     * @param targetIndex
     * @return
     */
    public List<String> getSystemsTargetStaticAnalyse(String sysId, Map<String, Double> targetStatic, Map<String, List<Object>> targetIndex) {
        List<String> header = new ArrayList<>();
        //查询体系下所有的目标
        List<String> targetList = redisUseService.getSystemsTargetList(sysId);
        if (CollectionUtil.isNotEmpty(targetList)) {
            //获取目标指标头部数据
            Set<String> s = new HashSet<>();
            for (String targetId : targetList) {
                if (redisUtil.hasKey(RedisName.SYSTEMS_TARGET_SUB_LEVEL_VALUE + "_" + targetId + "_" + 1)) {
                    Map<Object, Object> indexMap = redisUtil.hmget(RedisName.SYSTEMS_TARGET_SUB_LEVEL_VALUE + "_" + targetId + "_" + 1);
                    for (Object key : indexMap.keySet()) {
                        s.add(FileElseUtil.getObjectToString(key));
                    }
                }
            }
            header.addAll(s);
            header.add("分值");
            //获取目标实际指标数据
            for (String targetId : targetList) {
                double total = 0;
                List<Object> target = new ArrayList<>();
                if (header.size() > 1) {
                    if (redisUtil.hasKey(RedisName.SYSTEMS_TARGET_SUB_LEVEL_VALUE + "_" + targetId + "_" + 1)) {
                        for (int i = 0; i < header.size() - 1; i++) {
                            Map<Object, Object> indexMap = redisUtil.hmget(RedisName.SYSTEMS_TARGET_SUB_LEVEL_VALUE + "_" + targetId + "_" + 1);
                            double value = FileElseUtil.getObjectToDouble(indexMap.get(header.get(i)));
                            total += value;
                            target.add(value);
                        }
                    } else {
                        for (int i = 0; i < header.size() - 1; i++) {
                            target.add(0D);
                        }
                    }
                }
                target.add(total);
                targetStatic.put(targetId, total);
                targetIndex.put(targetId, target);
            }
        }
        return header;
    }

    public List<String> getRuleAnalyse(String sysId, Map<String, Double> targetRule, Map<String, List<Object>> targetIndex) {
        //头部
        List<String> header = new ArrayList<>();
        header.add("历史停驻飞机");
        header.add("驻停位置得分");
        header.add("近三年演习次数得分");
        header.add("分值");
        //目标具体
        List<String> targetList = redisUseService.getSystemsTargetList(sysId);
        if (CollectionUtil.isNotEmpty(targetList)) {
            List<SystemsDynamic> dynamics = systemsDynamicService.lambdaQuery().eq(SystemsDynamic::getSysId, sysId).eq(SystemsDynamic::getType, 1).list();
            if (CollectionUtil.isNotEmpty(dynamics)) {
                Map<String, Map<String, Double>> valueMap = new HashMap<>();
                //得分计算
                dynamics.forEach(data -> {
                    //得分
                    if (null != data.getNumber() && StringUtils.isNotBlank(data.getPostureId()) && StringUtils.isNotBlank(data.getTargetId())) {
                        Map<String, Double> m = new HashMap<>();
                        if (null != valueMap.get(data.getTargetId())) {
                            m = valueMap.get(data.getTargetId());
                        }
                        String key = redisUseService.getPostureTypeName(data.getPostureId());
                        double value = 0;
                        PostureComputeType computeType = postureComputeTypeService.getById(data.getPostureId());
                        if (ObjectUtil.isNotEmpty(computeType)) {
                            if ("1".equals(computeType.getComputeType())) {
                                JSONObject object = JSONObject.parseObject(computeType.getComputeParam());
                                value = object.getDouble("field") * data.getNumber();
                            } else {
                                JSONArray array = JSONArray.parseArray(computeType.getComputeParam());
                                if (CollectionUtil.isNotEmpty(array)) {
                                    for (int i = 0; i < array.size(); i++) {
                                        JSONObject object = array.getJSONObject(i);
                                        int minValue = FileElseUtil.getObjectToInt(object.getInteger("minValue"));
                                        int maxValue = FileElseUtil.getObjectToInt(object.getInteger("maxValue"));
                                        if (data.getNumber() >= minValue && data.getNumber() < maxValue) {
                                            value = FileElseUtil.getObjectToDouble(object.getDouble("score"));
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        m.put(key, value);
                        valueMap.put(data.getTargetId(), m);
                    }
                });
                for (String targetId : targetList) {
                    List<Object> target = new ArrayList<>();
                    String stay_target = "";
                    double stay_score = 0;
                    Map<String, Double> map = valueMap.get(targetId);
                    if (ObjectUtil.isNotEmpty(map)) {
                        int sign = 0;
                        for (String s : map.keySet()) {
                            if (0 == sign) {
                                stay_target = s;
                            } else {
                                stay_target += "," + s;
                            }
                            stay_score += map.get(s);
                            sign++;
                        }
                    }
                    target.add(stay_target);
                    target.add(stay_score);
                    target.add(0);
                    target.add(stay_score);
                    targetIndex.put(targetId, target);
                    targetRule.put(targetId, stay_score);
                }
            } else {
                for (String targetId : targetList) {
                    List<Object> index = new ArrayList<>();
                    for (int i = 0; i < 4; i++) {
                        index.add(0D);
                    }
                    targetIndex.put(targetId, index);
                    targetRule.put(targetId, 0D);
                }
            }
        }
        return header;
    }

    public List<String> getActiveAnalyse(String sysId, Map<String, Double> targetActive, Map<String, List<Object>> targetIndex) {
        //头部
        List<String> header = new ArrayList<>();
        header.add("停驻机型");
        header.add("分值");
        //目标具体
        List<String> targetList = redisUseService.getSystemsTargetList(sysId);
        if (CollectionUtil.isNotEmpty(targetList)) {
            List<SystemsDynamic> dynamics = systemsDynamicService.lambdaQuery().eq(SystemsDynamic::getSysId, sysId).eq(SystemsDynamic::getType, 2).list();
            if (CollectionUtil.isNotEmpty(dynamics)) {
                Map<String, Map<String, Double>> valueMap = new HashMap<>();
                //得分计算
                dynamics.forEach(data -> {
                    //得分
                    if (null != data.getNumber() && StringUtils.isNotBlank(data.getPostureId()) && StringUtils.isNotBlank(data.getTargetId())) {
                        Map<String, Double> m = new HashMap<>();
                        if (null != valueMap.get(data.getTargetId())) {
                            m = valueMap.get(data.getTargetId());
                        }
                        String key = redisUseService.getPostureTypeName(data.getPostureId());
                        double value = 0;
                        PostureComputeType computeType = postureComputeTypeService.getById(data.getPostureId());
                        if (ObjectUtil.isNotEmpty(computeType)) {
                            if ("1".equals(computeType.getComputeType())) {
                                JSONObject object = JSONObject.parseObject(computeType.getComputeParam());
                                value = object.getDouble("field") * data.getNumber();
                            } else {
                                JSONArray array = JSONArray.parseArray(computeType.getComputeParam());
                                if (CollectionUtil.isNotEmpty(array)) {
                                    for (int i = 0; i < array.size(); i++) {
                                        JSONObject object = array.getJSONObject(i);
                                        int minValue = FileElseUtil.getObjectToInt(object.getInteger("minValue"));
                                        int maxValue = FileElseUtil.getObjectToInt(object.getInteger("maxValue"));
                                        if (data.getNumber() >= minValue && data.getNumber() < maxValue) {
                                            value = FileElseUtil.getObjectToDouble(object.getDouble("score"));
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        m.put(key, value);
                        valueMap.put(data.getTargetId(), m);
                    }
                });
                for (String targetId : targetList) {
                    List<Object> target = new ArrayList<>();
                    String stay_target = "";
                    double stay_score = 0;
                    Map<String, Double> map = valueMap.get(targetId);
                    if (ObjectUtil.isNotEmpty(map)) {
                        int sign = 0;
                        for (String s : map.keySet()) {
                            if (0 == sign) {
                                stay_target = s;
                            } else {
                                stay_target += "," + s;
                            }
                            stay_score += map.get(s);
                            sign++;
                        }
                    }
                    target.add(stay_target);
                    target.add(stay_score);
                    targetIndex.put(targetId, target);
                    targetActive.put(targetId, stay_score);
                }
            } else {
                for (String targetId : targetList) {
                    List<Object> index = new ArrayList<>();
                    index.add("");
                    index.add(0D);
                    targetIndex.put(targetId, index);
                    targetActive.put(targetId, 0D);
                }
            }
        }
        return header;
    }

    public List<String> getIntentionAnalyse(String sysId, Map<String, Double> targetIntention, Map<String, List<Object>> targetIndex) {
        //头部
        List<String> header = new ArrayList<>();
        header.add("分值");
        //目标具体
        List<String> targetList = redisUseService.getSystemsTargetList(sysId);
        if (CollectionUtil.isNotEmpty(targetList)) {
            List<SystemsDynamic> dynamics = systemsDynamicService.lambdaQuery().eq(SystemsDynamic::getSysId, sysId).eq(SystemsDynamic::getType, 3).list();
            if (CollectionUtil.isNotEmpty(dynamics)) {
                Map<String, Double> numMap = new HashMap<>();
                //得分计算
                dynamics.forEach(data -> {
                    //得分
                    if (null != data.getNumber() && StringUtils.isNotBlank(data.getTargetId())) {
                        double value = FileElseUtil.getObjectToDouble(data.getNumber());
                        double old = 0;
                        if (null != numMap.get(data.getTargetId())) {
                            old = numMap.get(data.getTargetId());
                        }
                        numMap.put(data.getTargetId(), old + value);
                    }
                });
                for (String targetId : targetList) {
                    List<Object> target = new ArrayList<>();
                    double stay_score = FileElseUtil.getObjectToDouble(numMap.get(targetId));
                    target.add(stay_score);
                    targetIndex.put(targetId, target);
                    targetIntention.put(targetId, stay_score);
                }
            } else {
                for (String targetId : targetList) {
                    List<Object> index = new ArrayList<>();
                    index.add(0D);
                    targetIndex.put(targetId, index);
                    targetIntention.put(targetId, 0D);
                }
            }
        }
        return header;
    }

    public List<String> getRelationAnalyse(String sysId, Map<String, Double> targetRelation, Map<String, List<Object>> targetIndex) {
        List<String> header = new ArrayList<>();
        //计算体系单个目标得分
        List<String> targetList = redisUseService.getSystemsTargetList(sysId);
        List<TargetData> targetData = targetMapper.getTargetList(targetList);
        Map<String, Object> valueMap = new HashMap<>();
        targetData.forEach(data -> {
            valueMap.put(data.getTargetId(), FileElseUtil.getObjectToDouble(data.getIndexValue()));
        });
        Map<String, Double> targetValue = new HashMap<>();
        List<SystemsRelationship> list = targetMapper.getSystemsToMap(sysId);
        //计算体系关系目标之间得分
        Map<String, List<String>> rList = new HashMap<>();
        int size = 0;
        if (CollectionUtil.isNotEmpty(list)) {
            for (SystemsRelationship ship : list) {
                double tV = 0;
                if (ship.getPoint().contains("1指向")) {
                    List<String> r = new ArrayList<>();
                    if (null != rList.get(ship.getTargetOne())) {
                        r = rList.get(ship.getTargetOne());
                    }
                    r.add(FileElseUtil.getObjectToString(redisUtil.hget(RedisName.TARGET_BASE_DATA_ALL + "_" + ship.getTargetTwo(), "targetName")));
                    r.add(FileElseUtil.getObjectToString(valueMap.get(ship.getTargetTwo())));
                    if (r.size() > size) {
                        size = r.size();
                    }
                    rList.put(ship.getTargetOne(), r);
                    if (null != targetValue.get(ship.getTargetOne())) {
                        tV = FileElseUtil.getObjectToDouble(targetValue.get(ship.getTargetOne()));
                    }
                    targetValue.put(ship.getTargetOne(), tV + FileElseUtil.getObjectToDouble(valueMap.get(ship.getTargetTwo())));
                } else if (ship.getPoint().contains("2指向")) {
                    List<String> r = new ArrayList<>();
                    if (null != rList.get(ship.getTargetTwo())) {
                        r = rList.get(ship.getTargetTwo());
                    }
                    r.add(FileElseUtil.getObjectToString(redisUtil.hget(RedisName.TARGET_BASE_DATA_ALL + "_" + ship.getTargetOne(), "targetName")));
                    r.add(FileElseUtil.getObjectToString(valueMap.get(ship.getTargetOne())));
                    if (r.size() > size) {
                        size = r.size();
                    }
                    rList.put(ship.getTargetTwo(), r);
                    if (null != targetValue.get(ship.getTargetTwo())) {
                        tV = FileElseUtil.getObjectToDouble(targetValue.get(ship.getTargetTwo()));
                    }
                    targetValue.put(ship.getTargetTwo(), tV + FileElseUtil.getObjectToDouble(valueMap.get(ship.getTargetOne())));
                }
            }
        }
        if (size > 0) {
            int sign = 1;
            int middle = 1;
            for (int i = 0; i < size; i++) {
                if (middle == 1) {
                    header.add("关联子目标" + sign);
                    middle++;
                } else {
                    header.add("得分");
                    middle = 1;
                    sign++;
                }
            }
        }
        header.add("分值");
        //目标关联得分排序
        if (CollectionUtil.isNotEmpty(targetList)) {
            for (String targetId : targetList) {
                //关联关系记录
                List<Object> t = new ArrayList<>();
                if (size > 0 ) {
                    if (null != rList.get(targetId)) {
                        List<String> strings = rList.get(targetId);
                        for (String str : strings) {
                            t.add(str);
                        }
                        if (size - strings.size() > 0) {
                            for (int i = 0; i < size - strings.size(); i++) {
                                t.add("");
                            }
                        }
                    } else {
                        for (int i = 0; i < size; i++) {
                            t.add("");
                        }
                    }
                }
                t.add(FileElseUtil.getObjectToDouble(targetValue.get(targetId)));
                targetRelation.put(targetId, FileElseUtil.getObjectToDouble(targetValue.get(targetId)));
                targetIndex.put(targetId, t);
            }
        }
        return header;
    }

}
